<template>
	<view class="html-gender">
		<view class="uni-container">
			<uni-forms ref="form" :value="requiestForm" validateTrigger="bind">
				<uni-forms-item name="url" label="url" required>
					<uni-easyinput v-model="requiestForm.url" />
				</uni-forms-item>
				<uni-forms-item name="request_data" label="请求参数">
					<!-- <vue-json-editor v-model="jsonStr" :mode="'code'" lang="zh"></vue-json-editor> -->
					<!-- <JsonEditorVue class="editor" v-model="jsonStr" /> -->
					<view style="border: 1px solid;">
						<acqui-monaco-editor :defautVal="defautArgs" style="width: 100%;height: 500rpx;"
							ref="monacoEditor"></acqui-monaco-editor>
					</view>
				</uni-forms-item>
				<uni-forms-item name="request_methce" label="请求方式">
					<el-select size="small" style="max-width: 250rpx;" v-model="requiestForm.request_methce"
						value-key="name" placeholder="请选择">
						<el-option v-for="(item, index) in requistList" :key="index" :label="item" :value="item">
						</el-option>
					</el-select>
				</uni-forms-item>
				<uni-forms-item name="useData" label="响应数据选取" required>
					<uni-easyinput v-model="requiestForm.useData" placeholder="请输入响应数据选取:如data,则代表取res.data"/>
				</uni-forms-item>

				<view class="uni-button-group">
					<button type="primary" class="uni-button" style="width: 100px;" @click="submit">提交</button>
					<navigator open-type="navigateBack" style="margin-left: 15px;"><button class="uni-button"
							style="width: 100px;">返回</button></navigator>
				</view>
			</uni-forms>
		</view>
		<open-alert ref="openAlert" :AlertClass="1" @closeAlert="closeAlert">
			<uni-forms ref="form2">
				<el-card class="box-card">
					<view class="left_panal">
						<view class="">映射列表信息</view>
						<view class="map_item" v-for="(item, index) in formItemList" :key="index">
							<view>
								<text class="map_to">{{ item.mapped_to }}&nbsp;&nbsp;&nbsp;:&nbsp;&nbsp;&nbsp;</text>
								<template v-if="item.mapping_field.length>0">
									<text v-for="(item2, index2) in item.mapping_field"
										:key="index2">{{ item2 }}&gt;</text>
								</template>
								<template v-else>
									<text>""</text>
								</template>
							</view>
							<text class="remove_btn" @tap="removeFormItem(index)">-</text>
						</view>
					</view>
					<view class="right_panal">
						<div slot="header" class="clearfix">
							<span>数据映射设置</span>
							<view>
								<el-button type="primary" :disabled="isCangender" size="small" @click="gengderJson">
									{{ generateBtn }}
								</el-button>
								<el-button type="info" size="small" :disabled="!isGenerate" @click="copyJson">复制json
								</el-button>
								<el-button type="success" size="small" :disabled="!isGenerate">
									<template v-if="!isGenerate">
										下载
									</template>
									<template v-else>
										<a class="down_btn"
											:href="'data:text/json;charset=utf-8,' + JSON.stringify(dataJson)"
											download="data.txt">下载数据</a>
									</template>
								</el-button>
								<el-button type="warning" size="small" :disabled="!isGenerate" @click="addTo">批量加入
								</el-button>
							</view>
						</div>
						<!-- 表单信息 -->
						<view class="cell_one">
							<uni-forms-item label="映射字段" required>
								<el-tooltip effect="dark" content="从响应数据中选择需要的字段仅数组类型哦~" placement="top"><i
										class="info_desc el-icon-question"></i></el-tooltip>
								<el-cascader v-model="currentFormItem.mapping_field" placeholder="请选择要映射的字段" clearable
									:options="options" filterable></el-cascader>
							</uni-forms-item>
							<uni-forms-item label="映射到">
								<el-tooltip effect="dark" content="映射到新json中的哪个字段. 如obj.name" placement="top"><i
										class="info_desc el-icon-question"></i></el-tooltip>
								<el-input v-model="currentFormItem.mapped_to" placeholder="请输入映射到新json的哪个字段里">
								</el-input>
							</uni-forms-item>
							<el-button class="add_confirm_btn" type="success" size="small" @click="addMap">确认
							</el-button>

							<!-- 移除 -->
							<!-- <el-button v-if="index != 0" class="add_btn" type="danger" icon="el-icon-minus" circle @tap="removeFormItem(index)"></el-button> -->
							<!-- 增加 -->
							<!-- <el-button class="add_btn" type="success" icon="el-icon-plus" circle @tap="formItemList.push({})"></el-button> -->
						</view>
						<acqui-monaco-editor style="height: 60vh;" mountId="showMonaco" :isOnyRead="true"
							ref="monacoEditor2" @addItem="addItem"></acqui-monaco-editor>
						<!-- <vue-json-editor class="editore" v-model="dataJson" :mode="'code'" lang="zh"></vue-json-editor> -->
					</view>
				</el-card>
			</uni-forms>
		</open-alert>
	</view>
</template>

<script>
	export default {
		// components: {
		// 	JsonEditorVue
		// },
		data() {
			return {
				requiestForm: {
					url: 'https://aibizhi.isoyu.com/v1/vertical/category/4e4d610cdf714d2966000002/vertical',
					request_data: '',
					request_methce: 'POST',
					useData:'res'//用于数据列表的渲染
				},
				jsonStr: {
					word: '风景'
				}, //请求参数
				requistList: ['GET', 'POST'], //请求方式列表
				dataJson: '{}', //返回数据  生成json
				oldDataJson: {}, //生成前的json
				isGenerate: false, //是否生成了数据
				generateBtn: '生成', //生成按钮  生成or还原
				formItemList: [], //映射设置表单列表
				currentFormItem: {
					//当前映射值 输入框里的
					mapping_field: '',
					mapped_to: ''
				},
				options: [
					// {
					// 	value: 'zhinan',
					// 	label: '指南',
					// 	children: [
					// 		{
					// 			value: 'shejiyuanze',
					// 			label: '设计原则',
					// 			children: [
					// 				{
					// 					value: 'yizhi',
					// 					label: '一致'
					// 				},
					// 				{
					// 					value: 'fankui',
					// 					label: '反馈'
					// 				},
					// 				{
					// 					value: 'xiaolv',
					// 					label: '效率'
					// 				},
					// 				{
					// 					value: 'kekong',
					// 					label: '可控'
					// 				}
					// 			]
					// 		},
					// 	]
					// },
				],
				defautArgs: `{
	"limit": "48",
	"skip": "47",
	"order": "hot",
	"adult": "true",
	"first": "0"
}
			`
			};
		},
		computed: {
			// 是否可以生成
			isCangender() {
				const data = this.formItemList;
				return data.length <= 0;
			}
		},
		methods: {
			/**
			 * 触发表单提交
			 */
			async submit(e) {
				// uni.showLoading({
				// 	mask: true
				// });
				this.requiestForm.request_data = JSON.parse(this.$refs.monacoEditor.getEdiValue());
				const res = await this.$http(this.requiestForm.url, this.requiestForm.request_data);
				this.dataJson = res[this.requiestForm.useData];

				/**
				 * 使用递归生成下拉选择值
				 */
				let option = [];
				const getKeys = (obj, father) => {
					if (typeof obj != 'object') return; //这里需要限制一下进来的只能是object类型
					for (const key in obj) {
						// console.log('key===>', key);
						const val = obj[key];
						// 需要判断它的值是否为null
						// 判断它的类型，如果是object则说明其可能拥有子级
						if (val && typeof val == 'object') {
							const type = val.length ? 'array' : 'object';
							const curentVal = {
								label: key + '  ---' + type,
								value: key,
								type: type,
								children: []
							};
							father ? father.push(curentVal) : option.push(curentVal);
							// 进入这里说明该属性可能有子级，这时我们需要进行递归直到没有为止
							// 注意一点：如果值为数组对象时我们只需取其第一项即可
							// 通过length即可判断是object or  array
							getKeys(val.length ? val[0] : val, curentVal.children);
						} else {
							const type = obj[key] != null ? typeof obj[key] : null;
							father
								?
								father.push({
									label: key + '---' + type,
									value: key,
									type: type
								}) :
								option.push({
									label: key + '---' + type,
									value: key,
									type: type
								});
						}
					}
				};
				getKeys(res[this.requiestForm.useData]);
				
				this.options = [];
				option.forEach((item, index) => {
					if (item.type == 'array') {
						this.options.push(item);
					}
				});
				this.$refs.openAlert.Show();
			},
			// 移除表单一项
			removeFormItem(index) {
				this.formItemList.splice(index, 1);
			},
			// 生成json
			gengderJson() {
				if (this.generateBtn == '生成') {
					this.generateBtn = '还原';
					this.isGenerate = true;
					this.oldDataJson = {
						...this.dataJson
					};
					let resArr = [];
					// 遍历相应的list数据
					this.dataJson[this.formItemList[0]['mapping_field'][0]].forEach(item => {
						let mappedToJson = {};
						for (let item2 of this.formItemList) {
							if (!item2.mapping_field) {
								// 如果没填写映射字段就  将值设置为空字符串
								mappedToJson[item2.mapped_to] = '';
								continue;
							}
							// 获取要映射的字段
							let str = '';
							let mapping_field_arr = [...item2['mapping_field']];
							mapping_field_arr.splice(0, 1);
							mapping_field_arr.forEach(item3 => {
								str += '.' + item3;
							});
							str = str.substring(1);
							// 获取要映射的值
							const mappingVal = this.$utils.getObjValue(str, item);
							// 设置映射到的结构
							let fatherJson;
							const mappedTo = item2['mapped_to'].split('.');
							// 开始处理
							mappedTo.forEach((item4, index) => {
								// 如果有fatherJson那么就将其子级的值设置为{}以便子级操作，否则就是首级
								fatherJson ? (fatherJson[item4] = {}) : (mappedToJson[item4] = {});
								if (fatherJson && index >= mappedTo.length - 1) {
									// 对象的 最后一个属性，可以设置自己想要的值
									fatherJson[item4] = mappingVal;
								} else if (mappedTo.length == 1) {
									mappedToJson[item4] = mappingVal;
								}
								// 将fatherJson设置为当前所在的json环境
								fatherJson = fatherJson ? fatherJson[item4] : mappedToJson[item4];
							});
						}
						resArr.push(mappedToJson);
					});
					uni.showToast({
						title: '生成成功！共' + resArr.length + '条数据',
						icon: 'none',
						duration: 2000
					});
					this.dataJson = resArr;
				} else {
					// 还原JSON
					this.generateBtn = '生成';
					this.dataJson = {
						...this.oldDataJson
					};
				}
			},
			// json中选中的内容
			addItem(val) {},
			// 添加到映射列表
			addMap() {
				if (!this.currentFormItem.mapped_to) {
					uni.showToast({
						title: '请填写映射信息！',
						icon: 'none'
					});
					return;
				}
				this.formItemList.push({
					mapping_field: this.currentFormItem.mapping_field,
					mapped_to: this.currentFormItem.mapped_to
				});
				this.currentFormItem = {
					mapping_field: '',
					mapped_to: ''
				};
			},
			// 关闭弹窗
			closeAlert() {
				this.generateBtn = '生成';
				this.dataJson = {
					...this.oldDataJson
				};
			},
			copyJson() {
				uni.setClipboardData({
					data: JSON.stringify(this.dataJson),
					success: () => {
						this.$message({
							showClose: true,
							message: '数据复制成功!',
							type: 'success',
							center: true
						});
					}
				});
			}
		},
		watch: {
			dataJson: function(val) {
				this.$nextTick(() => {
					this.$refs.monacoEditor2.setDefaltVal(JSON.stringify(val));
				});
			}
		}
	};
</script>

<style lang="less" scoped>
	.html-gender {
		/deep/ .el-card__body {
			display: flex;

			.left_panal {
				width: 30%;

				.map_item {
					padding: 50rpx 0;
					padding-right: 30rpx;
					display: flex;
					align-items: center;
					justify-content: space-between;

					.map_to {
						color: #499045;
					}

					.remove_btn {
						flex-shrink: 0;
						background-color: #85c4e5;
						border-radius: 50%;
						font-size: 30rpx;
						display: inline-block;
						color: white;
						width: 50rpx;
						height: 50rpx;
						text-align: center;
						line-height: 50rpx;
						font-weight: bold;
						cursor: pointer;
					}
				}
			}

			.right_panal {
				width: 70%;
				padding-left: 30rpx;
				border-left: 1px dashed #e2d8d8;

				.clearfix {
					margin-bottom: 30rpx;
					display: flex;
					align-items: center;
					justify-content: space-between;

					.down_btn {
						color: white;
						text-decoration: none;
						padding: 10rpx 20rpx;
					}
				}
			}
		}

		.box-card {
			width: 600rpx;
		}

		@media screen and (min-width: 800px) {
			.box-card {
				width: 900px;
			}
		}

		.editore {
			/deep/ .jsoneditor-vue {
				height: 900rpx;
			}
		}

		.img_sty {
			width: 200rpx;
			height: 200rpx;
			border-radius: 10rpx;
		}

		.el-tag {
			margin-right: 20rpx;
		}

		.el-tag+.el-tag {
			margin-bottom: 20rpx;
			margin-right: 20rpx;
		}

		.button-new-tag {
			margin-right: 20rpx;
			height: 32px;
			line-height: 30px;
			padding-top: 0;
			padding-bottom: 0;
		}

		.input-new-tag {
			width: 90px;
			vertical-align: bottom;
		}

		.cell_one {
			display: flex;
			justify-content: space-around;
			align-items: center;
			margin-bottom: 30rpx;

			/deep/ .uni-forms-item__content {
				display: flex;
				align-items: center;
			}

			/deep/ .uni-forms-item__label {
				width: auto !important;
			}

			.info_desc {
				margin-right: 20rpx;
			}

			/deep/ .uni-forms-item__inner {
				padding-bottom: 0;
			}

			.add_confirm_btn {
				margin-left: 20rpx;
			}

			// .add_btn {
			// 	width: 50rpx;
			// 	height: 50rpx;
			// 	padding: 10rpx;
			// 	margin-top: 15rpx;
			// }
		}
	}
</style>
